﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using SpeedikonCom;

namespace SOM.Objects
{
  [Serializable()]
  [ComDefaultInterface(typeof(SOM.Interfaces.Objects.IWall)), ClassInterface(ClassInterfaceType.None)]
  [ComSourceInterfaces(typeof(SOM.Interfaces.Objects.IWall))]
  public partial class Wall : SOM.Interfaces.Objects.IWall
  {

    public void SendToDatabase(string server, string table, string SchemeFilePath = "")
    {
      SOM.Helper.Methods.SendToDatabase<SOM.Objects.Wall>(this, server,table,SchemeFilePath);
    }
    public void GetFromDatabase(string server, int ID, string table, string SchemeFilePath = "")
    {
      var tmp = (SOM.Interfaces.Objects.IWall)SOM.Helper.Methods.GetFromDatabase<SOM.Objects.Wall>(server, ID,table,SchemeFilePath);
      foreach (System.Reflection.PropertyInfo p in this.GetType().GetProperties())
      {
        try { this.GetType().GetProperty(p.Name).SetValue(this, tmp.GetType().GetProperty(p.Name).GetValue(tmp, null), null); }
        catch { }
      }
    }

    public object GetCustomAttribute(string AttributeName, SOM.Helper.enums.ReturnType ReturnType, out int iRet)
    {
        int lStatus = 0;
        int Anz;
        double dVal = 0;
        double[] daVal = null;
        int lVal = 0;
        int[] laVal = null;
        string sVal = null;
        string[] saVal = null;
        object ret = null;

        int Typ = (int)SOM.Helper.enums.ObjektTypen.Wall;
        IEZ_sp_Attribute cAttribut = new IEZ_sp_Attribute();
        switch (ReturnType)
        {
            case SOM.Helper.enums.ReturnType.Double :
                dVal = 0;
          cAttribut.GetDouble((int)Typ, ID, AttributeName, out dVal, out lStatus);
          if (lStatus == 0)
          {
            ret = dVal;
          }
          
                break;
            case SOM.Helper.enums.ReturnType.DoubleArray:
                daVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
          cAttribut.GetDoubleArray(Typ, ID, AttributeName, 0, Anz, out daVal, out lStatus);
          if (lStatus == 0)
          {
            ret =  daVal;
          }
                break;
            case SOM.Helper.enums.ReturnType.Integer:
            lVal = 0;
          cAttribut.GetInt(Typ, ID, AttributeName, out lVal, out lStatus);
          if (lStatus == 0)
          {
           ret =  lVal;
          }
                break;
            case SOM.Helper.enums.ReturnType.IntegerArray:
             laVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
          cAttribut.GetIntArray(Typ, ID, AttributeName, 0, Anz, out laVal, out lStatus);
          if (lStatus == 0)
          {
            ret = laVal;
          }
                break;
            case SOM.Helper.enums.ReturnType.String:
            sVal = null;
          cAttribut.GetChar(Typ, ID, AttributeName, out sVal, out lStatus);
          if (lStatus == 0)
          {
            ret = sVal;
          }
                break;
            case SOM.Helper.enums.ReturnType.StringArray:
             saVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, AttributeName, out Anz, out lStatus);
          cAttribut.GetCharArray(Typ, ID, AttributeName, 0, Anz, out saVal, out lStatus);
          if (lStatus == 0)
          {
            ret = saVal;
          }
                break;
            default:
                lStatus = -9999;
                break;
        }
        iRet = lStatus;
        return ret;
    }

    #region "COM-GUIDs"
    // Diese GUIDs stellen die COM-Identität für diese Klasse 
    // und ihre COM-Schnittstellen bereit. Wenn Sie sie ändern, können vorhandene 
    // Clients nicht mehr auf die Klasse zugreifen.
    public const string ClassId = "4FE693CC-7C2E-4737-8EE4-5B4BB3D7F9EA";
    public const string InterfaceId = "71E1DDF0-0FB6-4CF8-965F-F5EF4609B89C";
    public const string EventsId = "65175DF6-B130-4E2D-AE8A-FA661CA44541";
    #endregion

    public Wall()
    {
      //initWand();
      _props = this.GetType().GetProperties();
    }

    private System.Reflection.PropertyInfo[] _props;

    [ComVisible(false)]
    const string sWandName = "Wand";
    [ComVisible(false)]
    const string sWandZellName = "WALL__";

    [ComVisible(false)]
    private Dictionary<string, int> ldObjektTyp = new Dictionary<string, int>();
    [ComVisible(false)]
    private List<string> scObjektName = new List<string>();
    [ComVisible(false)]
    private Dictionary<string, string> sdObjektZellName = new Dictionary<string, string>();
    [ComVisible(false)]
    private Dictionary<string, Dictionary<string, string>> sddObjektAttribut = new Dictionary<string, Dictionary<string, string>>();

    private string ArrayToString(object[] arr)
    {
      System.Text.StringBuilder s = new System.Text.StringBuilder();
      s.Append("{");
      bool first = true;
      foreach (object x in arr)
      {
        if (first)
        {
          first = false;
          s.Append(x.ToString());
        }
        else
        {
          s.Append(", " + x.ToString());
        }
      }
      s.Append("}");
      return s.ToString();
    }

    public T GetValueByName<T>(string Name)
    {
      return (T)this.GetType().GetProperty(Name).GetValue(this, null);
    }
    public object GetValueByName(string Name)
    {
      return this.GetType().GetProperty(Name).GetValue(this, null);
    }

    public Type GetTypeFromName(string Name)
    {
      return this.GetType().GetProperty(Name).GetValue(this, null).GetType();
    }

    [NonSerialized()]
    internal bool _readOnly = false;
    internal void SetPropertiesReadOnly(bool ReadOnly)
    {
      _readOnly = ReadOnly;
    }

    public bool  Delete()
    {
      IEZ_sp_Object o = new IEZ_sp_Object();
      int iRet;
      o.Delete((int)SOM.Helper.enums.ObjektTypen.Wall, this.ID, out iRet);
      if (iRet != 0)
        return false;
      else
        return true;
    }

    public bool Place(ref SOM.Helper.Types.Point3d Origin)
    {
      IEZ_sp_Wall w = new IEZ_sp_Wall();
      int iRet;
      w.InitPlace(20, this.A_PROTOTYPE, out iRet);
      if (iRet != 0)
        return false;
      else
      {
        w.Place(this.StartPointAxis.X + Origin.X, this.StartPointAxis.Y + Origin.Y, this.EndPointAxis.X + Origin.X, this.EndPointAxis.Y + Origin.Y, out iRet);
        if (iRet != 0)
          return false;
        else
          return true;
      }
    }

    public void LoadWall(int WallID)
    {
      List<string> sdObjektName = new List<string>();
      Dictionary<string, string> sddOjektAttribut = new Dictionary<string, string>();

      Dictionary<string, string> sdAttribute = new Dictionary<string, string>();
      IEZ_sp_Wall clWall = new IEZ_sp_Wall();
      IEZ_sp_Object clObject = new IEZ_sp_Object();

      double xs, ys, xe, ye, wb;
      int counter;
      counter = 0;


      int iRet;

      SOM.Helper.Types.Point3d point1 = new SOM.Helper.Types.Point3d();
      SOM.Helper.Types.Point3d point2 = new SOM.Helper.Types.Point3d();

      point1.X = 0;
      point1.Y = 0;
      point1.Z = 0;
      point2.X = 0;
      point2.Y = 0;
      point2.Z = 0;



      clWall.GetCenterAxisPoints(WallID, out xs, out ys, out xe, out ye, out wb, out iRet);
      counter = counter + 1;

      this.ID = WallID;
      point1.X = Math.Round(xs, 2, MidpointRounding.AwayFromZero);
      point1.Y = Math.Round(ys, 2, MidpointRounding.AwayFromZero);
      point1.Z = 0;
      point2.X = Math.Round(xe, 2, MidpointRounding.AwayFromZero);
      point2.Y = Math.Round(ye, 2, MidpointRounding.AwayFromZero);
      point2.Z = 0;
      this.StartPointCenter = point1;
      this.EndPointCenter = point2;



      this.Angle = SOM.Helper.Methods.Winkel(point1, point2);

      this.Width = wb;



      #region "Generic Property Setter"
      int lStatus;

      int Anz = 0;

      double dVal = 0;
      double[] daVal = null;
      int lVal = 0;
      int[] laVal = null;
      string sVal = null;
      string[] saVal = null;

      int Typ = (int)SOM.Helper.enums.ObjektTypen.Wall;
      IEZ_sp_Attribute cAttribut = new IEZ_sp_Attribute();



      foreach (System.Reflection.PropertyInfo p in _props)
      {
        if (p.PropertyType == typeof(double))
        {
          dVal = 0;
          cAttribut.GetDouble((int)Typ, ID, p.Name, out dVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, dVal, null);
          }
        }
        else if (p.PropertyType == typeof(double[]))
        {
          daVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetDoubleArray(Typ, ID, p.Name, 0, Anz, out daVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, daVal, null);
          }
        }
        else if (p.PropertyType == typeof(int))
        {
          lVal = 0;
          cAttribut.GetInt(Typ, ID, p.Name, out lVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, lVal, null);
          }
        }
        else if (p.PropertyType == typeof(int[]))
        {
          laVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetIntArray(Typ, ID, p.Name, 0, Anz, out laVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, laVal, null);
          }
        }
        else if (p.PropertyType == typeof(string))
        {
          sVal = null;
          cAttribut.GetChar(Typ, ID, p.Name, out sVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, sVal, null);
          }
        }
        else if (p.PropertyType == typeof(string[]))
        {
          saVal = null;
          Anz = 0;
          cAttribut.GetArraySize(Typ, ID, p.Name, out Anz, out lStatus);
          cAttribut.GetCharArray(Typ, ID, p.Name, 0, Anz, out saVal, out lStatus);
          if (lStatus == 0)
          {
            this.GetType().GetProperty(p.Name).SetValue(this, saVal, null);
          }
        }
      }
      #endregion


      double w = this.Angle;

      if (w < 0)
        w = 360 + w;
      w += 90;
      if (w >= 360)
        w -= 360;
      this.StartPointAxis = SOM.Helper.Methods.GetPointPolar(this.StartPointCenter, w, ((this.Width / 2) - Math.Abs(this.A_AXIS_OFFSET)), true, 4);
      this.EndPointAxis = SOM.Helper.Methods.GetPointPolar(this.EndPointCenter, w, ((this.Width / 2) - Math.Abs(this.A_AXIS_OFFSET)), true, 4);


      this.Length = SOM.Helper.Methods.GetDistancePoint2D(this.StartPointAxis, this.EndPointAxis);


      this.SetPropertiesReadOnly(true);


    }

  }

}
